<?php
declare (strict_types = 1);

namespace app\adminapi\listener;

use app\common\model\system\AdminOperateLogModel;
use think\Exception;
use think\Model;
use think\Response;
/**
 * 管理员操作日志记录监听器
 */
class AdminOperateLog extends Model
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle(Response $response)
    {
        //是否开启记录日志
        if(!config('project.admin_operate_log.open') || empty(config('project.admin_operate_log.allow_methods'))){
            return true;
        }

        $request = request();
        //具体哪些请求类型需要记录日志
        if(!in_array('*',config('project.admin_operate_log.allow_methods')) && !in_array($request->method(),config('project.admin_operate_log.allow_methods'))){
            return true;
        }

        //计算当前请求耗时
        $use_time = sprintf('%.2f',microtime(true) - $request->time(true));

        try{
            //不需要记录访问日志的判断
            if(!$request->controllerObject || $request->controllerObject->isNotNeedOperateLog()){
                return true;
            }

            //其它不记录日志的规则

            //获取控制器方法中的注释作为操作名称
            $rc = new \ReflectionClass($request->controllerObject);
            $doc = $rc->getMethod($request->action())->getDocComment();
            if($doc && preg_match('/\s(\w+)/u', $doc, $matches)){
                $action_name = trim($matches[0]);
            }else{
                $action_name = $rc->getName().'->'.$request->action();//获取默认的操作名称（类名->方法）
            }
        }catch (\Exception $e){
            $action_name = $rc->getName().'->'.$request->action();//获取默认的操作名称（类名->方法）
        }

        $params = $request->param();

        $result = $response->getContent();
        $request_status = 1;
        if($response->getCode() !== 200){
            $request_status = 0;
        }

        try{
            $data = [
                'admin_id' => $request->adminInfo['admin_id'] ?? 0,
                'admin_name' => $request->adminInfo['name'] ?? '',
                'admin_username' => $request->adminInfo['username'] ?? '',
                'action_name' => $action_name,
                'request_method' => $request->method(),
                'request_url' => $request->url(),
                'request_status' => $request_status,
                'params' => json_encode($params,JSON_UNESCAPED_UNICODE),
                'ip' => $request->ip(),
                'user_agent' => $request->header('user_agent'),
                'result' => $result,
                'use_time' => max($use_time, 0)
            ];
            if(!AdminOperateLogModel::create($data)){
                return false;
            }
        }catch (\Exception $e){}
    }
}
